﻿'=====================================================================
'模 块 名：BoyiLog

'描    述：log日志存储模块，提供文件和数据库方式

'依赖模块："Provider=Microsoft.Jet.OLEDB.4.0;Data Source=" 或
'          "Provider=Microsoft.ACE.OLEDB.12.0;Data Source=" 

'使用方法：(1)配置好属性
'          (2)调用WriteLogxxxx()等

'原始版本：1.00
'作    者：刘德亮
'完成日期：2020-3-11

'修改版本：1.01
'修改作者：刘德亮
'修改日期：2021-6-6
'修改记录：1.模块改为类方式，各常量定义改为属性可运行时改变
'          2.一次打开/ 一次关闭“数据库”
'=====================================================================
Imports System.Data.OleDb
Imports System.IO

Namespace FL_8x0.Common

    Public Class BoyiLog
        '存储方式选择
        Private LOG_SAVE_FILE As Boolean = True         'TXT文件方式
        Private LOG_SAVE_DATABASE As Boolean = False    'mdb数据库方式

        '"Microsoft.Jet.OLEDB.4.0"
        '"Microsoft.ACE.OLEDB.12.0" 
        Private strDatabaseProvider As String = "Microsoft.ACE.OLEDB.12.0"

        '日志开关
        Private LOG_ERROR As Boolean = True         '错误，影响使用
        Private LOG_WARN As Boolean = True          '警告，可能产生问题
        Private LOG_INFO As Boolean = False         '正常输出信息
        Private LOG_DEBUG As Boolean = False        '调试输出信息
        Private LOG_ASSERT As Boolean = False       '断言输出信息

        '提示框开关
        Private LOG_ERROR_MSGBOX As Boolean = True      '错误，影响使用
        Private LOG_WARN_MSGBOX As Boolean = True       '警告，可能产生问题
        Private LOG_INFO_MSGBOX As Boolean = False      '正常输出信息
        Private LOG_DEBUG_MSGBOX As Boolean = False     '调试输出信息
        Private LOG_ASSERT_MSGBOX As Boolean = False    '断言输出信息

        '类属性用
        Private strLogPath As String '日志文件和数据库目录
        Private strUserName As String '当前用户名

        Private dbLogConnection As OleDbConnection 'log数据库句柄



        '=====================================================================
        '函 数 名: New
        '参    数: 
        '返 回 值:
        '功能描述: 构造函数
        '=====================================================================
        Public Sub New()
            strLogPath = AppDomain.CurrentDomain.BaseDirectory & "Log" '程序启动运行目录
            strUserName = "空"

            If Not Directory.Exists(strLogPath) Then
                Directory.CreateDirectory(strLogPath) '创建目录
            End If

            dbLogConnection = Nothing
        End Sub


        Public Sub Dispose()
            Try
                '关闭log数据库
                If Not IsNothing(dbLogConnection) Then
                    dbLogConnection.Close()
                End If
            Catch ex As Exception
                MsgBox(ex.Message, MsgBoxStyle.OkOnly, "Log错误")
            End Try

            strLogPath = ""
            strUserName = "未命名"
        End Sub


        '=====================================================================
        '属 性 名: LogPath
        '功能描述: 日志文件和数据库目录
        '=====================================================================
        Public Property LogPath() As String
            Get
                Return strLogPath
            End Get

            Set(ByVal value As String)
                '变更前先关闭
                If strLogPath <> value Then
                    Try
                        '关闭log数据库
                        If Not IsNothing(dbLogConnection) Then
                            dbLogConnection.Close()
                            dbLogConnection = Nothing
                        End If
                    Catch ex As Exception
                        MsgBox(ex.Message & vbCrLf & "LogPath()", MsgBoxStyle.OkOnly, "错误")
                    End Try
                End If

                If value = "" Then '空
                    strLogPath = AppDomain.CurrentDomain.BaseDirectory & "Log"   '程序启动运行目录
                ElseIf Directory.Exists(value) Then
                    strLogPath = value
                Else
                    strLogPath = AppDomain.CurrentDomain.BaseDirectory & "Log"  '程序启动运行目录
                End If

                If Not Directory.Exists(strLogPath) Then
                    Directory.CreateDirectory(strLogPath) '创建目录
                End If
            End Set
        End Property


        '=====================================================================
        '属 性 名: UserName
        '功能描述: 当前用户名
        '=====================================================================
        Public Property UserName() As String
            Get
                Return strUserName
            End Get

            Set(ByVal value As String)
                strUserName = value
            End Set
        End Property


        '=====================================================================
        '属 性 名: LOG_SAVE_FILE_EN
        '功能描述: 文件型日志
        '=====================================================================
        Public Property LOG_SAVE_FILE_EN() As Boolean
            Get
                Return LOG_SAVE_FILE
            End Get

            Set(ByVal value As Boolean)
                LOG_SAVE_FILE = value
            End Set
        End Property


        '=====================================================================
        '属 性 名: LOG_SAVE_DATABASE_EN
        '功能描述: 数据库型日志
        '=====================================================================
        Public Property LOG_SAVE_DATABASE_EN() As Boolean
            Get
                Return LOG_SAVE_DATABASE
            End Get

            Set(ByVal value As Boolean)
                LOG_SAVE_DATABASE = value
            End Set
        End Property


        '=====================================================================
        '属 性 名: DatabaseProvider
        '功能描述: 数据库调用接口
        '=====================================================================
        Public Property DatabaseProvider() As String
            Get
                Return strDatabaseProvider
            End Get

            Set(ByVal value As String)
                strDatabaseProvider = value
            End Set
        End Property


        '=====================================================================
        '属 性 名: LOG_ERROR_EN
        '功能描述: ERROR开关
        '=====================================================================
        Public Property LOG_ERROR_EN() As Boolean
            Get
                Return LOG_ERROR
            End Get

            Set(ByVal value As Boolean)
                LOG_ERROR = value
            End Set
        End Property


        '=====================================================================
        '属 性 名: LOG_WARN_EN
        '功能描述: WARN开关
        '=====================================================================
        Public Property LOG_WARN_EN() As Boolean
            Get
                Return LOG_WARN
            End Get

            Set(ByVal value As Boolean)
                LOG_WARN = value
            End Set
        End Property


        '=====================================================================
        '属 性 名: LOG_INFO_EN
        '功能描述: INFO开关
        '=====================================================================
        Public Property LOG_INFO_EN() As Boolean
            Get
                Return LOG_INFO
            End Get

            Set(ByVal value As Boolean)
                LOG_INFO = value
            End Set
        End Property


        '=====================================================================
        '属 性 名: LOG_DEBUG_EN
        '功能描述: DEBUG开关
        '=====================================================================
        Public Property LOG_DEBUG_EN() As Boolean
            Get
                Return LOG_DEBUG
            End Get

            Set(ByVal value As Boolean)
                LOG_DEBUG = value
            End Set
        End Property


        '=====================================================================
        '属 性 名: LOG_ASSERT_EN
        '功能描述: ASSERT开关
        '=====================================================================
        Public Property LOG_ASSERT_EN() As Boolean
            Get
                Return LOG_ASSERT
            End Get

            Set(ByVal value As Boolean)
                LOG_ASSERT = value
            End Set
        End Property


        '=====================================================================
        '属 性 名: LOG_ERROR_MSGBOX_EN
        '功能描述: ERROR提示框开关
        '=====================================================================
        Public Property LOG_ERROR_MSGBOX_EN() As Boolean
            Get
                Return LOG_ERROR_MSGBOX
            End Get

            Set(ByVal value As Boolean)
                LOG_ERROR_MSGBOX = value
            End Set
        End Property


        '=====================================================================
        '属 性 名: LOG_WARN_MSGBOX_EN
        '功能描述: WARN提示框开关
        '=====================================================================
        Public Property LOG_WARN_MSGBOX_EN() As Boolean
            Get
                Return LOG_WARN_MSGBOX
            End Get

            Set(ByVal value As Boolean)
                LOG_WARN_MSGBOX = value
            End Set
        End Property


        '=====================================================================
        '属 性 名: LOG_INFO_MSGBOX_EN
        '功能描述: INFO提示框开关
        '=====================================================================
        Public Property LOG_INFO_MSGBOX_EN() As Boolean
            Get
                Return LOG_INFO_MSGBOX
            End Get

            Set(ByVal value As Boolean)
                LOG_INFO_MSGBOX = value
            End Set
        End Property


        '=====================================================================
        '属 性 名: LOG_DEBUG_MSGBOX_EN
        '功能描述: DEBUG提示框开关
        '=====================================================================
        Public Property LOG_DEBUG_MSGBOX_EN() As Boolean
            Get
                Return LOG_DEBUG_MSGBOX
            End Get

            Set(ByVal value As Boolean)
                LOG_DEBUG_MSGBOX = value
            End Set
        End Property


        '=====================================================================
        '属 性 名: LOG_ASSERT_MSGBOX_EN
        '功能描述: ASSERT提示框开关
        '=====================================================================
        Public Property LOG_ASSERT_MSGBOX_EN() As Boolean
            Get
                Return LOG_ASSERT_MSGBOX
            End Get

            Set(ByVal value As Boolean)
                LOG_ASSERT_MSGBOX = value
            End Set
        End Property


        '=====================================================================
        '函 数 名: WriteLogFile
        '参    数: strLevel = 等级
        '          strSource = 来源
        '          strMessage = 信息
        '返 回 值:
        '功能描述: log日志信息存储到文件
        '          每天一个文件，防止单个文件过大
        '          只记录关键数据，防止影响通讯的处理效率
        '=====================================================================
        Private Sub WriteLogFile(strLevel As String, strSource As String, strMessage As String)
            If LOG_SAVE_FILE = True Then
                Try
                    '打开log文件
                    Dim strFileName As String = strLogPath & "\" & Format(Now(), "yyyy-MM-dd") & ".log"
                    Dim swLogFile As StreamWriter = New StreamWriter(strFileName, True, System.Text.Encoding.UTF8)   '追加写入模式

                    '准备写入信息
                    Dim strData As String = "["
                    strData &= CStr(Now()) & "], ["
                    strData &= strLevel & "], ["
                    strData &= strUserName & "], ["
                    strData &= strSource & "], ["
                    strData &= strMessage & "]"

                    swLogFile.WriteLine(strData)
                    swLogFile.Close()

                Catch ex As Exception
                    MsgBox(ex.Message & vbCrLf & "WriteLogFile()", MsgBoxStyle.OkOnly, "错误")
                End Try
            End If
        End Sub



        '=====================================================================
        '函 数 名: WriteLogDatabase
        '参    数: strLevel = 等级
        '          strSource = 来源
        '          strMessage = 信息
        '返 回 值:
        '功能描述: log日志信息存储到数据库
        '          只记录关键数据，防止影响通讯的处理效率
        '=====================================================================
        Private Sub WriteLogDatabase(strLevel As String, strSource As String, strMessage As String)
            If LOG_SAVE_DATABASE = True Then
                Try
                    '打开log数据库
                    If IsNothing(dbLogConnection) Then
                        '文件名
                        Dim strFileName As String = strLogPath & "\" & "日志记录.mdb"

                        If Not System.IO.File.Exists(strFileName) Then '文件不存在
                            WriteLogFile("Error", "WriteLogDatabase()", "日志记录.mdb 文件不存在!")
                            Return
                        End If

                        Dim strConn As String = "Provider=" & strDatabaseProvider & ";Data Source=" & strFileName & ";Persist Security Info=False;Jet OLEDB:Database Password=" & SUPER_USER_NAME & SUPER_PASSWORD
                        dbLogConnection = New OleDbConnection(strConn)
                        dbLogConnection.Open()
                    End If

                Catch ex As Exception
                    WriteLogFile("Error", "WriteLogDatabase()", ex.Message)
                    Return
                End Try

                Try
                    '添加记录
                    Dim strCmd As String = "INSERT INTO 日志记录 ( [LogDate], [Level], [Source], [Message], [UserName] ) "
                    strCmd &= "VALUES ( #" & CStr(Now()) & "#, '" & Mid(strLevel, 1, 250) & "', '" & Mid(strSource, 1, 2048) & "', '" & Mid(strMessage, 1, 2048) & "', '" & Mid(strUserName, 1, 250) & "' )"

                    Dim dbCmd As New OleDbCommand(strCmd)
                    dbCmd.Connection = dbLogConnection

                    dbCmd.ExecuteNonQuery()

                    dbCmd = Nothing

                Catch ex As Exception
                    WriteLogFile("Error", "WriteLogDatabase()", ex.Message)
                    Return
                End Try

            End If
        End Sub



        '=====================================================================
        '函 数 名: WriteLog
        '参    数: strLevel = 等级
        '          strSource = 来源
        '          strMessage = 信息
        '返 回 值:
        '功能描述: log日志信息存储
        '          每天一个文件，防止单个文件过大
        '          只记录关键数据，防止影响通讯的处理效率
        '=====================================================================
        Private Sub WriteLog(strLevel As String, strSource As String, strMessage As String)
            WriteLogFile(strLevel, strSource, strMessage) '写文件
            WriteLogDatabase(strLevel, strSource, strMessage) '写数据库
        End Sub



        '=====================================================================
        '函 数 名: WriteLogError
        '参    数: strSource = 来源
        '          strMessage = 信息
        '返 回 值:
        '功能描述: log日志信息存储（等级：错误）
        '=====================================================================
        Public Sub WriteLogError(strSource As String, strMessage As String)
            If LOG_ERROR = True Then
                WriteLog("Error", strSource, strMessage)

                If LOG_ERROR_MSGBOX = True Then
                    MsgBox(strSource & vbCrLf & vbCrLf & strMessage,
                           MsgBoxStyle.OkOnly + MsgBoxStyle.ApplicationModal + MsgBoxStyle.Critical, "错误")
                End If
            End If
        End Sub



        '=====================================================================
        '函 数 名: WriteLogWarn
        '参    数: strSource = 来源
        '          strMessage = 信息
        '返 回 值:
        '功能描述: log日志信息存储（等级：警告）
        '=====================================================================
        Public Sub WriteLogWarn(strSource As String, strMessage As String)
            If LOG_WARN = True Then
                WriteLog("Warn", strSource, strMessage)

                If LOG_WARN_MSGBOX = True Then
                    MsgBox(strSource & vbCrLf & vbCrLf & strMessage,
                           MsgBoxStyle.OkOnly + MsgBoxStyle.ApplicationModal + MsgBoxStyle.Exclamation, "警告")
                End If
            End If
        End Sub



        '=====================================================================
        '函 数 名: WriteLogInfo
        '参    数: strSource = 来源
        '          strMessage = 信息
        '          strUserName = 当前用户名称
        '返 回 值:
        '功能描述: log日志信息存储（等级：正常输出信息）
        '=====================================================================
        Public Sub WriteLogInfo(strSource As String, strMessage As String)
            If LOG_INFO = True Then
                WriteLog("Info", strSource, strMessage)

                If LOG_INFO_MSGBOX = True Then
                    MsgBox(strSource & vbCrLf & vbCrLf & strMessage,
                           MsgBoxStyle.OkOnly + MsgBoxStyle.ApplicationModal + MsgBoxStyle.Information, "信息")
                End If
            End If
        End Sub



        '=====================================================================
        '函 数 名: WriteLogDebug
        '参    数: strSource = 来源
        '          strMessage = 信息
        '          strUserName = 当前用户名称
        '返 回 值:
        '功能描述: log日志信息存储（等级：调试输出信息）
        '=====================================================================
        Public Sub WriteLogDebug(strSource As String, strMessage As String)
            If LOG_DEBUG = True Then
                WriteLog("Debug", strSource, strMessage)

                If LOG_DEBUG_MSGBOX = True Then
                    MsgBox(strSource & vbCrLf & vbCrLf & strMessage,
                           MsgBoxStyle.OkOnly + MsgBoxStyle.ApplicationModal, "调试")
                End If
            End If
        End Sub



        '=====================================================================
        '函 数 名: WriteLogAssert
        '参    数: strSource = 来源
        '          strMessage = 信息
        '返 回 值:
        '功能描述: log日志信息存储（等级：断言输出信息）
        '=====================================================================
        Public Sub WriteLogAssert(strSource As String, strMessage As String)
            If LOG_ASSERT = True Then
                WriteLog("Assert", strSource, strMessage)

                If LOG_ASSERT_MSGBOX = True Then
                    MsgBox(strSource & vbCrLf & vbCrLf & strMessage,
                           MsgBoxStyle.OkOnly + MsgBoxStyle.ApplicationModal, "条件检查")
                End If
            End If
        End Sub


    End Class
End Namespace